﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using log4net;
using NServiceBus.Management.Managers.Impl;
using NServiceBus.Management.Messages.Status;

namespace NServiceBus.Management
{
    public class EndpointManager : ManagerBase, IEndpointManager

    {

        private int refreshInterval = 10;

        public int RefreshInterval
        {
            set
            {
                refreshInterval = value;
            }
        }
        private readonly Timer heartbeat;

        public StatusManager StatusManager{ get; set;}

        private static readonly ILog logger = LogManager.GetLogger(typeof(EndpointManager));


        public EndpointManager()
        {
            heartbeat = new Timer(ExecuteHeartbeat, null, int.MaxValue, int.MaxValue);
        }

        public void Start()
        {
            EnableHeartbeat(0);

            Bus.Send(new OnlineMessage());
        }

        public void Stop()
        {
            DisableHeartbeat();

            Bus.Send(new OfflineMessage());

            //statusManager.EndpointStatus = StatusManager.Status.Stopped;
        }

        private void DisableHeartbeat()
        {
            //disable heartbeat
            heartbeat.Change(int.MaxValue, int.MaxValue);
        }

        private void EnableHeartbeat(long elapsedMilliseconds)
        {
            long due = refreshInterval * 1000 - elapsedMilliseconds;
            due = (due < 0 ? 0 : due);

            //enable heartbeat 
            heartbeat.Change(due, refreshInterval * 1000);
        }

        public void ExecuteHeartbeat(object state)
        {
            DisableHeartbeat();

            var watch = new Stopwatch();
            watch.Start();

            try
            {
                StatusManager.SendEndpointStatus();

                //add more heartbeat functions here
            }
            catch (Exception ex)
            {
                logger.Fatal(ex);
            }
            finally
            {
                watch.Stop();
            }

            EnableHeartbeat(watch.ElapsedMilliseconds);
        }


    }
}
